chosen.jquery.js ➔ ctor   F
last analyzed

Complexity

Conditions 88

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 88
eloc 1
dl 0
loc 1
rs 0
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like chosen.jquery.js ➔ ctor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
// Chosen, a Select Box Enhancer for jQuery and Prototype
2
// by Patrick Filler for Harvest, http://getharvest.com
3
//
4
// Version 0.13.0
5
// Full source at https://github.com/harvesthq/chosen
6
// Copyright (c) 2011 Harvest http://getharvest.com
7
8
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
9
// This file is generated by `grunt build`, do not edit it by hand.
10
(function() {
11
  var SelectParser;
12
13
  SelectParser = (function() {
14
    function SelectParser() {
15
      this.options_index = 0;
16
      this.parsed = [];
17
    }
18
19
    SelectParser.prototype.add_node = function(child) {
20
      if (child.nodeName.toUpperCase() === "OPTGROUP") {
21
        return this.add_group(child);
22
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
23
        return this.add_option(child);
24
      }
25
    };
26
27
    SelectParser.prototype.add_group = function(group) {
28
      var group_position, option, _i, _len, _ref, _results;
29
30
      group_position = this.parsed.length;
31
      this.parsed.push({
32
        array_index: group_position,
33
        group: true,
34
        label: this.escapeExpression(group.label),
35
        children: 0,
36
        disabled: group.disabled
37
      });
38
      _ref = group.childNodes;
39
      _results = [];
40
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
41
        option = _ref[_i];
42
        _results.push(this.add_option(option, group_position, group.disabled));
43
      }
44
      return _results;
45
    };
46
47
    SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
48
      if (option.nodeName.toUpperCase() === "OPTION") {
49
        if (option.text !== "") {
50
          if (group_position != null) {
51
            this.parsed[group_position].children += 1;
52
          }
53
          this.parsed.push({
54
            array_index: this.parsed.length,
55
            options_index: this.options_index,
56
            value: option.value,
57
            text: option.text,
58
            html: option.innerHTML,
59
            selected: option.selected,
60
            disabled: group_disabled === true ? group_disabled : option.disabled,
61
            group_array_index: group_position,
62
            classes: option.className,
63
            style: option.style.cssText
64
          });
65
        } else {
66
          this.parsed.push({
67
            array_index: this.parsed.length,
68
            options_index: this.options_index,
69
            empty: true
70
          });
71
        }
72
        return this.options_index += 1;
73
      }
74
    };
75
76
    SelectParser.prototype.escapeExpression = function(text) {
77
      var map, unsafe_chars;
78
79
      if ((text == null) || text === false) {
80
        return "";
81
      }
82
      if (!/[\&\<\>\"\'\`]/.test(text)) {
83
        return text;
84
      }
85
      map = {
86
        "<": "&lt;",
87
        ">": "&gt;",
88
        '"': "&quot;",
89
        "'": "&#x27;",
90
        "`": "&#x60;"
91
      };
92
      unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
93
      return text.replace(unsafe_chars, function(chr) {
94
        return map[chr] || "&amp;";
95
      });
96
    };
97
98
    return SelectParser;
99
100
  })();
101
102
  SelectParser.select_to_array = function(select) {
103
    var child, parser, _i, _len, _ref;
104
105
    parser = new SelectParser();
106
    _ref = select.childNodes;
107
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
108
      child = _ref[_i];
109
      parser.add_node(child);
110
    }
111
    return parser.parsed;
112
  };
113
114
  this.SelectParser = SelectParser;
115
116
}).call(this);
117
118
(function() {
119
  var AbstractChosen, root;
120
121
  root = this;
122
123
  AbstractChosen = (function() {
124
    function AbstractChosen(form_field, options) {
125
      this.form_field = form_field;
126
      this.options = options != null ? options : {};
127
      if (!AbstractChosen.browser_is_supported()) {
128
        return;
129
      }
130
      this.is_multiple = this.form_field.multiple;
131
      this.set_default_text();
132
      this.set_default_values();
133
      this.setup();
134
      this.set_up_html();
135
      this.register_observers();
136
      this.finish_setup();
137
    }
138
139
    AbstractChosen.prototype.set_default_values = function() {
140
      var _this = this;
141
142
      this.click_test_action = function(evt) {
143
        return _this.test_active_click(evt);
144
      };
145
      this.activate_action = function(evt) {
146
        return _this.activate_field(evt);
147
      };
148
      this.active_field = false;
149
      this.mouse_on_container = false;
150
      this.results_showing = false;
151
      this.result_highlighted = null;
152
      this.result_single_selected = null;
153
      this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
154
      this.disable_search_threshold = this.options.disable_search_threshold || 0;
155
      this.disable_search = this.options.disable_search || false;
156
      this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
157
      this.group_search = this.options.group_search != null ? this.options.group_search : true;
158
      this.search_contains = this.options.search_contains || false;
159
      this.single_backstroke_delete = this.options.single_backstroke_delete || false;
160
      this.max_selected_options = this.options.max_selected_options || Infinity;
161
      return this.inherit_select_classes = this.options.inherit_select_classes || false;
162
    };
163
164
    AbstractChosen.prototype.set_default_text = function() {
165
      if (this.form_field.getAttribute("data-placeholder")) {
166
        this.default_text = this.form_field.getAttribute("data-placeholder");
167
      } else if (this.is_multiple) {
168
        this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
169
      } else {
170
        this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
171
      }
172
      return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
173
    };
174
175
    AbstractChosen.prototype.mouse_enter = function() {
176
      return this.mouse_on_container = true;
177
    };
178
179
    AbstractChosen.prototype.mouse_leave = function() {
180
      return this.mouse_on_container = false;
181
    };
182
183
    AbstractChosen.prototype.input_focus = function(evt) {
184
      var _this = this;
185
186
      if (this.is_multiple) {
187
        if (!this.active_field) {
188
          return setTimeout((function() {
189
            return _this.container_mousedown();
190
          }), 50);
191
        }
192
      } else {
193
        if (!this.active_field) {
194
          return this.activate_field();
195
        }
196
      }
197
    };
198
199
    AbstractChosen.prototype.input_blur = function(evt) {
200
      var _this = this;
201
202
      if (!this.mouse_on_container) {
203
        this.active_field = false;
204
        return setTimeout((function() {
205
          return _this.blur_test();
206
        }), 100);
207
      }
208
    };
209
210
    AbstractChosen.prototype.results_option_build = function(options) {
211
      var content, data, _i, _len, _ref;
212
213
      content = '';
214
      _ref = this.results_data;
215
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
216
        data = _ref[_i];
217
        if (data.group && (data.search_match || data.group_match)) {
218
          content += this.result_add_group(data);
219
        } else if (!data.empty && data.search_match) {
220
          content += this.result_add_option(data);
221
        }
222
        if (options != null ? options.first : void 0) {
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
223
          if (data.selected && this.is_multiple) {
224
            this.choice_build(data);
225
          } else if (data.selected && !this.is_multiple) {
226
            this.single_set_selected_text(data.text);
227
          }
228
        }
229
      }
230
      return content;
231
    };
232
233
    AbstractChosen.prototype.result_add_option = function(option) {
234
      var classes, style;
235
236
      classes = [];
237
      if (!option.disabled && !(option.selected && this.is_multiple)) {
238
        classes.push("active-result");
239
      }
240
      if (option.disabled && !(option.selected && this.is_multiple)) {
241
        classes.push("disabled-result");
242
      }
243
      if (option.selected) {
244
        classes.push("result-selected");
245
      }
246
      if (option.group_array_index != null) {
247
        classes.push("group-option");
248
      }
249
      if (option.classes !== "") {
250
        classes.push(option.classes);
251
      }
252
      style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
253
      return "<li class=\"" + (classes.join(' ')) + "\"" + style + " data-option-array-index=\"" + option.array_index + "\"><span class=\"img\"></span>" + option.search_text + "</li>";
254
    };
255
256
    AbstractChosen.prototype.result_add_group = function(group) {
257
      return "<li class=\"group-result\">" + group.search_text + "</li>";
258
    };
259
260
    AbstractChosen.prototype.results_update_field = function() {
261
      this.set_default_text();
262
      if (!this.is_multiple) {
263
        this.results_reset_cleanup();
264
      }
265
      this.result_clear_highlight();
266
      this.result_single_selected = null;
267
      this.results_build();
268
      if (this.results_showing) {
269
        return this.winnow_results();
270
      }
271
    };
272
273
    AbstractChosen.prototype.results_toggle = function() {
274
      if (this.results_showing) {
275
        return this.results_hide();
276
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
277
        return this.results_show();
278
      }
279
    };
280
281
    AbstractChosen.prototype.results_search = function(evt) {
282
      if (this.results_showing) {
283
        return this.winnow_results();
284
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
285
        return this.results_show();
286
      }
287
    };
288
289
    AbstractChosen.prototype.winnow_results = function() {
290
      var option, regex, regexAnchor, results, searchText, startpos, text, zregex, _i, _len, _ref;
291
292
      this.no_results_clear();
293
      results = 0;
294
      searchText = this.get_search_text();
295
      regexAnchor = this.search_contains ? "" : "^";
296
      regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
297
      zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
298
      _ref = this.results_data;
299
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
300
        option = _ref[_i];
301
        if (!option.empty) {
302
          if (option.group) {
303
            option.group_match = false;
304
          }
305
          if (!(option.group && !this.group_search)) {
306
            option.search_match = false;
307
            option.search_text = option.group ? option.label : option.html;
308
            option.search_match = this.search_string_match(option.search_text, regex);
309
            if (option.search_match) {
310
              results += 1;
311
            }
312
            if (option.search_match) {
313
              if (searchText.length) {
314
                startpos = option.search_text.search(zregex);
315
                text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
316
                option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
317
              }
318
              if (option.group_array_index != null) {
319
                this.results_data[option.group_array_index].group_match = true;
320
              }
321
            } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
322
              option.search_match = true;
323
            }
324
          }
325
        }
326
      }
327
      if (results < 1 && searchText.length) {
328
        this.update_results_content("");
329
        this.result_clear_highlight();
330
        return this.no_results(searchText);
331
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
332
        this.update_results_content(this.results_option_build());
333
        return this.winnow_results_set_highlight();
334
      }
335
    };
336
337
    AbstractChosen.prototype.search_string_match = function(search_string, regex) {
338
      var part, parts, _i, _len;
339
340
      if (regex.test(search_string)) {
341
        return true;
342
      } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
343
        parts = search_string.replace(/\[|\]/g, "").split(" ");
344
        if (parts.length) {
345
          for (_i = 0, _len = parts.length; _i < _len; _i++) {
346
            part = parts[_i];
347
            if (regex.test(part)) {
348
              return true;
349
            }
350
          }
351
        }
352
      }
353
    };
354
355
    AbstractChosen.prototype.choices_count = function() {
356
      var option, _i, _len, _ref;
357
358
      if (this.selected_option_count != null) {
359
        return this.selected_option_count;
360
      }
361
      this.selected_option_count = 0;
362
      _ref = this.form_field.options;
363
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
364
        option = _ref[_i];
365
        if (option.selected) {
366
          this.selected_option_count += 1;
367
        }
368
      }
369
      return this.selected_option_count;
370
    };
371
372
    AbstractChosen.prototype.choices_click = function(evt) {
373
      evt.preventDefault();
374
      if (!(this.results_showing || this.is_disabled)) {
375
        return this.results_show();
376
      }
377
    };
378
379
    AbstractChosen.prototype.keyup_checker = function(evt) {
380
      var stroke, _ref;
381
382
      stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
383
      this.search_field_scale();
384
      switch (stroke) {
385
        case 8:
386
          if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
387
            return this.keydown_backstroke();
388
          } else if (!this.pending_backstroke) {
389
            this.result_clear_highlight();
390
            return this.results_search();
391
          }
392
          break;
393
        case 13:
394
          evt.preventDefault();
395
          if (this.results_showing) {
396
            return this.result_select(evt);
397
          }
398
          break;
399
        case 27:
400
          if (this.results_showing) {
401
            this.results_hide();
402
          }
403
          return true;
404
        case 9:
405
        case 38:
406
        case 40:
407
        case 16:
408
        case 91:
409
        case 17:
410
          break;
411
        default:
412
          return this.results_search();
413
      }
414
    };
415
416
    AbstractChosen.prototype.container_width = function() {
417
      if (this.options.width != null) {
418
        return this.options.width;
419
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
420
        return "" + this.form_field.offsetWidth + "px";
421
      }
422
    }
423
424
    AbstractChosen.prototype.generate_field_id = function() {
425
      return this.generate_random_id();
426
    };
427
428
    AbstractChosen.browser_is_supported = function() {
429
      var _ref;
430
431
      if (window.navigator.appName === "Microsoft Internet Explorer") {
432
        return (null !== (_ref = document.documentMode) && _ref >= 8);
433
      }
434
      return true;
435
    };
436
	AbstractChosen.prototype.search_results_touchstart = function(evt) {
437
      this.touch_started = true;
438
    };
439
440
    AbstractChosen.prototype.search_results_touchmove = function(evt) {
441
      this.touch_started = false;
442
    };
443
444
    AbstractChosen.prototype.search_results_touchend = function(evt) {
445
      if (this.touch_started) {
446
        return this.search_results_mouseup(evt);
447
      }
448
    };
449
    AbstractChosen.default_multiple_text = "Select Some Options";
450
451
    AbstractChosen.default_single_text = "Select an Option";
452
453
    AbstractChosen.default_no_result_text = "No results match";
454
455
    return AbstractChosen;
456
457
  })();
458
459
  root.AbstractChosen = AbstractChosen;
460
461
}).call(this);
462
463
(function() {
464
  var $, Chosen, root, _ref,
465
    __hasProp = {}.hasOwnProperty,
466
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
467
468
  root = this;
469
470
  $ = jQuery;
471
472
  $.fn.extend({
473
    chosen: function(options) {
474
      if (!AbstractChosen.browser_is_supported()) {
475
        return this;
476
      }
477
      return this.each(function(input_field) {
478
        var $this;
479
480
        $this = $(this);
481
        if (!$this.hasClass("chzn-done")) {
482
          return $this.data('chosen', new Chosen(this, options));
483
        }
484
      });
485
    },
486
    unchosen: function() {
487
      return $(this).each(function(input_field) {
488
        var chosen, element;
489
        element = $(this);
490
        chosen = element.data("chosen");
491
        if (chosen) {
492
          chosen.remove();
493
          element.data("chosen", null);
494
        }
495
        return element;
496
      });
497
    }
498
  });
499
500
  Chosen = (function(_super) {
501
    __extends(Chosen, _super);
502
503
    function Chosen() {
504
      _ref = Chosen.__super__.constructor.apply(this, arguments);
505
      return _ref;
506
    }
507
508
    Chosen.prototype.setup = function() {
509
      this.form_field_jq = $(this.form_field);
510
      this.current_selectedIndex = this.form_field.selectedIndex;
511
      return this.is_rtl = this.form_field_jq.hasClass("chzn-rtl");
512
    };
513
514
    Chosen.prototype.finish_setup = function() {
515
      return this.form_field_jq.addClass("chzn-done");
516
    };
517
518
    Chosen.prototype.set_up_html = function() {
519
      var container_classes, container_props;
520
521
      container_classes = ["chzn-container"];
522
      container_classes.push("chzn-container-" + (this.is_multiple ? "multi" : "single"));
523
      if (this.inherit_select_classes && this.form_field.className) {
524
        container_classes.push(this.form_field.className);
525
      }
526
      if (this.is_rtl) {
527
        container_classes.push("chzn-rtl");
528
      }
529
      container_props = {
530
        'class': container_classes.join(' '),
531
        'style': "width: " + (this.container_width()) + ";",
532
        'title': this.form_field.title
533
      };
534
      if (this.form_field.id.length) {
535
        container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chzn";
536
      }
537
      this.container = $("<div />", container_props);
538
      if (this.is_multiple) {
539
        this.container.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop"><ul class="chzn-results"></ul></div>');
540
      } else {
541
        this.container.html('<a href="javascript:void(0)" class="chzn-single chzn-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chzn-drop"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>');
542
      }
543
      this.form_field_jq.hide().after(this.container);
544
      this.dropdown = this.container.find('div.chzn-drop').first();
545
      this.search_field = this.container.find('input').first();
546
      this.search_results = this.container.find('ul.chzn-results').first();
547
      this.search_field_scale();
548
      this.search_no_results = this.container.find('li.no-results').first();
549
      if (this.is_multiple) {
550
        this.search_choices = this.container.find('ul.chzn-choices').first();
551
        this.search_container = this.container.find('li.search-field').first();
552
      } else {
553
        this.search_container = this.container.find('div.chzn-search').first();
554
        this.selected_item = this.container.find('.chzn-single').first();
555
      }
556
      this.results_build();
557
      this.set_tab_index();
558
      this.set_label_behavior();
559
      return this.form_field_jq.trigger("liszt:ready", {
560
        chosen: this
561
      });
562
    };
563
564
    Chosen.prototype.register_observers = function() {
565
      var _this = this;
566
567
      this.container.mousedown(function(evt) {
568
        _this.container_mousedown(evt);
569
      });
570
      this.container.mouseup(function(evt) {
571
        _this.container_mouseup(evt);
572
      });
573
      this.container.mouseenter(function(evt) {
574
        _this.mouse_enter(evt);
575
      });
576
      this.container.mouseleave(function(evt) {
577
        _this.mouse_leave(evt);
578
      });
579
	  this.container.bind('touchstart', function(evt) {
580
		  _this.container_mousedown(evt);
581
      });
582
      this.search_results.mouseup(function(evt) {
583
        _this.search_results_mouseup(evt);
584
      });
585
      this.search_results.mouseover(function(evt) {
586
        _this.search_results_mouseover(evt);
587
      });
588
      this.search_results.mouseout(function(evt) {
589
        _this.search_results_mouseout(evt);
590
      });
591
	  this.search_results.bind('touchstart', function(evt) {
592
		_this.search_results_touchstart(evt);
593
	  });
594
	  this.search_results.bind('touchmove', function(evt) {
595
        _this.search_results_touchmove(evt);
596
      });
597
	  this.search_results.bind('touchend', function(evt) {
598
		_this.search_results_touchend(evt);
599
	  });
600
      this.search_results.bind('mousewheel DOMMouseScroll', function(evt) {
601
        _this.search_results_mousewheel(evt);
602
      });
603
      this.form_field_jq.bind("liszt:updated", function(evt) {
604
        _this.results_update_field(evt);
605
      });
606
      this.form_field_jq.bind("liszt:activate", function(evt) {
607
        _this.activate_field(evt);
608
      });
609
      this.form_field_jq.bind("liszt:open", function(evt) {
610
        _this.container_mousedown(evt);
611
      });
612
      this.search_field.blur(function(evt) {
613
        _this.input_blur(evt);
614
      });
615
      this.search_field.keyup(function(evt) {
616
        _this.keyup_checker(evt);
617
      });
618
      this.search_field.keydown(function(evt) {
619
        _this.keydown_checker(evt);
620
      });
621
      this.search_field.focus(function(evt) {
622
        _this.input_focus(evt);
623
      });
624
      if (this.is_multiple) {
625
        return this.search_choices.click(function(evt) {
626
          _this.choices_click(evt);
627
        });
628
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
629
        return this.container.click(function(evt) {
630
          evt.preventDefault();
631
        });
632
      }
633
    };
634
    Chosen.prototype.unregister_observers = function() {
635
      return this.form_field_jq.unbind();
636
    };
637
638
    Chosen.prototype.remove_html = function() {
639
      this.form_field_jq.show().removeClass('chzn-done');
640
      return this.container.remove();
641
    };
642
643
    Chosen.prototype.unregister_observers = function() {
644
	return this.form_field_jq.unbind();
645
    };
646
647
    Chosen.prototype.remove_html = function() {
648
	this.form_field_jq.show().removeClass('chzn-done');
649
	return this.container.remove();
650
    };
651
652
    Chosen.prototype.search_field_disabled = function() {
653
      this.is_disabled = this.form_field_jq[0].disabled;
654
      if (this.is_disabled) {
655
        this.container.addClass('chzn-disabled');
656
        this.search_field[0].disabled = true;
657
        if (!this.is_multiple) {
658
          this.selected_item.unbind("focus", this.activate_action);
659
        }
660
        return this.close_field();
661
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
662
        this.container.removeClass('chzn-disabled');
663
        this.search_field[0].disabled = false;
664
        if (!this.is_multiple) {
665
          return this.selected_item.bind("focus", this.activate_action);
666
        }
667
      }
668
    };
669
670
    Chosen.prototype.container_mousedown = function(evt) {
671
      if (!this.is_disabled) {
672
        if (evt && evt.type === "mousedown" && !this.results_showing) {
673
          evt.preventDefault();
674
        }
675
        if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
676
          if (!this.active_field) {
677
            if (this.is_multiple) {
678
              this.search_field.val("");
679
            }
680
            $(document).click(this.click_test_action);
681
            this.results_show();
682
          } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chzn-single").length)) {
683
            evt.preventDefault();
684
            this.results_toggle();
685
          }
686
          return this.activate_field();
687
        }
688
      }
689
    };
690
691
    Chosen.prototype.container_mouseup = function(evt) {
692
      if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
693
        return this.results_reset(evt);
694
      }
695
    };
696
697
    Chosen.prototype.search_results_mousewheel = function(evt) {
698
      var delta, _ref1, _ref2;
699
700
      delta = -((_ref1 = evt.originalEvent) != null ? _ref1.wheelDelta : void 0) || ((_ref2 = evt.originialEvent) != null ? _ref2.detail : void 0);
0 ignored issues
show
Coding Style introduced by
Consider using undefined instead of void(0). It is equivalent and more straightforward to read.
Loading history...
701
      if (delta != null) {
702
        evt.preventDefault();
703
        if (evt.type === 'DOMMouseScroll') {
704
          delta = delta * 40;
705
        }
706
        return this.search_results.scrollTop(delta + this.search_results.scrollTop());
707
      }
708
    };
709
710
    Chosen.prototype.blur_test = function(evt) {
711
      if (!this.active_field && this.container.hasClass("chzn-container-active")) {
712
        return this.close_field();
713
      }
714
    };
715
716
    Chosen.prototype.close_field = function() {
717
      $(document).unbind("click", this.click_test_action);
718
      this.active_field = false;
719
      this.results_hide();
720
      this.container.removeClass("chzn-container-active");
721
      this.clear_backstroke();
722
      this.show_search_field_default();
723
      return this.search_field_scale();
724
    };
725
726
    Chosen.prototype.activate_field = function() {
727
      this.container.addClass("chzn-container-active");
728
      this.active_field = true;
729
      this.search_field.val(this.search_field.val());
730
      return this.search_field.focus();
731
    };
732
733
    Chosen.prototype.test_active_click = function(evt) {
734
      if (this.container.is($(evt.target).closest('.chzn-container'))) {
735
        return this.active_field = true;
736
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
737
        return this.close_field();
738
      }
739
    };
740
741
    Chosen.prototype.results_build = function() {
742
      this.parsing = true;
743
      this.selected_option_count = null;
744
      this.results_data = root.SelectParser.select_to_array(this.form_field);
745
      if (this.is_multiple) {
746
        this.search_choices.find("li.search-choice").remove();
747
      } else if (!this.is_multiple) {
748
        this.single_set_selected_text();
749
        if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
750
          this.search_field[0].readOnly = true;
751
          this.container.addClass("chzn-container-single-nosearch");
752
        } else {
753
          this.search_field[0].readOnly = false;
754
          this.container.removeClass("chzn-container-single-nosearch");
755
        }
756
      }
757
      this.update_results_content(this.results_option_build({
758
        first: true
759
      }));
760
      this.search_field_disabled();
761
      this.show_search_field_default();
762
      this.search_field_scale();
763
      return this.parsing = false;
764
    };
765
766
    Chosen.prototype.result_do_highlight = function(el) {
767
      var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
768
769
      if (el.length) {
770
        this.result_clear_highlight();
771
        this.result_highlight = el;
772
        this.result_highlight.addClass("highlighted");
773
        maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
774
        visible_top = this.search_results.scrollTop();
775
        visible_bottom = maxHeight + visible_top;
776
        high_top = this.result_highlight.position().top + this.search_results.scrollTop();
777
        high_bottom = high_top + this.result_highlight.outerHeight();
778
        if (high_bottom >= visible_bottom) {
779
          return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
780
        } else if (high_top < visible_top) {
781
          return this.search_results.scrollTop(high_top);
782
        }
783
      }
784
    };
785
786
    Chosen.prototype.result_clear_highlight = function() {
787
      if (this.result_highlight) {
788
        this.result_highlight.removeClass("highlighted");
789
      }
790
      return this.result_highlight = null;
791
    };
792
793
    Chosen.prototype.results_show = function() {
794
      if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
795
        this.form_field_jq.trigger("liszt:maxselected", {
796
          chosen: this
797
        });
798
        return false;
799
      }
800
      this.container.addClass("chzn-with-drop");
801
      this.form_field_jq.trigger("liszt:showing_dropdown", {
802
        chosen: this
803
      });
804
	  var windowHeight = $(window).height(),
805
		dropdownTop = this.container.offset().top + this.container.height() - $(window).scrollTop()
806
		totalHeight = this.dropdown.height() + dropdownTop
807
808
	  this.dropdown.toggleClass('chzn-above', totalHeight > windowHeight);
809
      this.results_showing = true;
810
      this.search_field.focus();
811
      this.search_field.val(this.search_field.val());
812
      return this.winnow_results();
813
    };
814
815
    Chosen.prototype.update_results_content = function(content) {
816
      return this.search_results.html(content);
817
    };
818
819
    Chosen.prototype.results_hide = function() {
820
      if (this.results_showing) {
821
        this.result_clear_highlight();
822
        this.container.removeClass("chzn-with-drop");
823
        this.form_field_jq.trigger("liszt:hiding_dropdown", {
824
          chosen: this
825
        });
826
      }
827
      return this.results_showing = false;
828
    };
829
830
    Chosen.prototype.reset_tab_index = function() {
831
      var tabbed_item;
832
      tabbed_item = this.is_multiple ? this.search_field : this.selected_item;
833
      this.form_field_jq.attr("tabindex",tabbed_item.attr("tabindex"));
834
      return tabbed_item.attr("tabindex") - 1;
835
    };
836
837
    Chosen.prototype.set_tab_index = function(el) {
838
      var ti;
839
840
      if (this.form_field_jq.attr("tabindex")) {
841
        ti = this.form_field_jq.attr("tabindex");
842
        this.form_field_jq.attr("tabindex", -1);
843
        return this.search_field.attr("tabindex", ti);
844
      }
845
    };
846
847
    Chosen.prototype.set_label_behavior = function() {
848
      var _this = this;
849
850
      this.form_field_label = this.form_field_jq.parents("label");
851
      if (!this.form_field_label.length && this.form_field.id.length) {
852
        this.form_field_label = $("label[for='" + this.form_field.id + "']");
853
      }
854
      if (this.form_field_label.length > 0) {
855
        return this.form_field_label.click(function(evt) {
856
          if (_this.is_multiple) {
857
            return _this.container_mousedown(evt);
858
          } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
859
            return _this.activate_field();
860
          }
861
        });
862
      }
863
    };
864
865
    Chosen.prototype.reset_tab_index = function() {
866
	var tabbed_item;
867
	tabbed_item = this.is_multiple ? this.search_field : this.selected_item;
868
	this.form_field_jq.attr("tabindex",tabbed_item.attr("tabindex"));
869
	return tabbed_item.attr("tabindex") - 1;
870
    };
871
872
    Chosen.prototype.show_search_field_default = function() {
873
      if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
874
        this.search_field.val(this.default_text);
875
        return this.search_field.addClass("default");
876
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
877
        this.search_field.val("");
878
        return this.search_field.removeClass("default");
879
      }
880
    };
881
882
    Chosen.prototype.search_results_mouseup = function(evt) {
883
      var target;
884
885
      target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
886
      if (target.length) {
887
        this.result_highlight = target;
888
        this.result_select(evt);
889
        return this.search_field.focus();
890
      }
891
    };
892
893
    Chosen.prototype.search_results_mouseover = function(evt) {
894
      var target;
895
896
      target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
897
      if (target) {
898
        return this.result_do_highlight(target);
899
      }
900
    };
901
902
    Chosen.prototype.search_results_mouseout = function(evt) {
903
      if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
904
        return this.result_clear_highlight();
905
      }
906
    };
907
908
    Chosen.prototype.choice_build = function(item) {
909
      var choice, close_link,
910
        _this = this;
911
912
      choice = $('<li />', {
913
        "class": "search-choice"
914
      }).html("<span>" + item.html + "</span>");
915
      if (item.disabled) {
916
        choice.addClass('search-choice-disabled');
917
      } else {
918
        close_link = $('<a />', {
919
          href: '#',
920
          "class": 'search-choice-close',
921
          rel: item.array_index
922
        });
923
        close_link.click(function(evt) {
924
          return _this.choice_destroy_link_click(evt);
925
        });
926
        choice.append(close_link);
927
      }
928
      return this.search_container.before(choice);
929
    };
930
931
    Chosen.prototype.choice_destroy_link_click = function(evt) {
932
      evt.preventDefault();
933
      evt.stopPropagation();
934
      if (!this.is_disabled) {
935
        return this.choice_destroy($(evt.target));
936
      }
937
    };
938
939
    Chosen.prototype.choice_destroy = function(link) {
940
      if (this.result_deselect(link.attr("rel"))) {
941
        this.show_search_field_default();
942
        if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
943
          this.results_hide();
944
        }
945
        link.parents('li').first().remove();
946
        return this.search_field_scale();
947
      }
948
    };
949
950
    Chosen.prototype.results_reset = function() {
951
      this.form_field.options[0].selected = true;
952
      this.selected_option_count = null;
953
      this.single_set_selected_text();
954
      this.show_search_field_default();
955
      this.results_reset_cleanup();
956
      this.form_field_jq.trigger("change");
957
      if (this.active_field) {
958
        return this.results_hide();
959
      }
960
    };
961
962
    Chosen.prototype.results_reset_cleanup = function() {
963
      this.current_selectedIndex = this.form_field.selectedIndex;
964
      return this.selected_item.find("abbr").remove();
965
    };
966
967
    Chosen.prototype.result_select = function(evt) {
968
      var high, item;
969
970
      if (this.result_highlight) {
971
        high = this.result_highlight;
972
        this.result_clear_highlight();
973
        if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
974
          this.form_field_jq.trigger("liszt:maxselected", {
975
            chosen: this
976
          });
977
          return false;
978
        }
979
        if (this.is_multiple) {
980
          high.removeClass("active-result");
981
        } else {
982
          this.search_results.find(".result-selected").removeClass("result-selected");
983
          this.result_single_selected = high;
984
        }
985
        high.addClass("result-selected");
986
        item = this.results_data[high[0].getAttribute("data-option-array-index")];
987
        item.selected = true;
988
        this.form_field.options[item.options_index].selected = true;
989
        this.selected_option_count = null;
990
        if (this.is_multiple) {
991
          this.choice_build(item);
992
        } else {
993
          this.single_set_selected_text(item.text);
994
        }
995
        if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
996
          this.results_hide();
997
        }
998
        this.search_field.val("");
999
        if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1000
          this.form_field_jq.trigger("change", {
1001
            'selected': this.form_field.options[item.options_index].value
1002
          });
1003
        }
1004
        this.current_selectedIndex = this.form_field.selectedIndex;
1005
        return this.search_field_scale();
1006
      }
1007
    };
1008
1009
    Chosen.prototype.single_set_selected_text = function(text) {
1010
      if (text == null) {
1011
        text = this.default_text;
1012
      }
1013
      if (text === this.default_text) {
1014
        this.selected_item.addClass("chzn-default");
1015
      } else {
1016
        this.single_deselect_control_build();
1017
        this.selected_item.removeClass("chzn-default");
1018
      }
1019
      return this.selected_item.find("span").text(text);
1020
    };
1021
1022
    Chosen.prototype.result_deselect = function(pos) {
1023
      var result_data;
1024
1025
      result_data = this.results_data[pos];
1026
      if (!this.form_field.options[result_data.options_index].disabled) {
1027
        result_data.selected = false;
1028
        this.form_field.options[result_data.options_index].selected = false;
1029
        this.selected_option_count = null;
1030
        this.result_clear_highlight();
1031
        if (this.results_showing) {
1032
          this.winnow_results();
1033
        }
1034
        this.form_field_jq.trigger("change", {
1035
          deselected: this.form_field.options[result_data.options_index].value
1036
        });
1037
        this.search_field_scale();
1038
        return true;
1039
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1040
        return false;
1041
      }
1042
    };
1043
1044
    Chosen.prototype.single_deselect_control_build = function() {
1045
      if (!this.allow_single_deselect) {
1046
        return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
1047
      }
1048
      if (!this.selected_item.find("abbr").length) {
1049
        this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1050
      }
1051
      return this.selected_item.addClass("chzn-single-with-deselect");
1052
    };
1053
1054
    Chosen.prototype.get_search_text = function() {
1055
      if (this.search_field.val() === this.default_text) {
1056
        return "";
1057
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1058
        return $('<div/>').text($.trim(this.search_field.val())).html();
1059
      }
1060
    };
1061
1062
    Chosen.prototype.winnow_results_set_highlight = function() {
1063
      var do_high, selected_results;
1064
1065
      selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1066
      do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1067
      if (do_high != null) {
1068
        return this.result_do_highlight(do_high);
1069
      }
1070
    };
1071
1072
    Chosen.prototype.no_results = function(terms) {
1073
      var no_results_html;
1074
1075
      no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1076
      no_results_html.find("span").first().html(terms);
1077
      return this.search_results.append(no_results_html);
1078
    };
1079
1080
    Chosen.prototype.no_results_clear = function() {
1081
      return this.search_results.find(".no-results").remove();
1082
    };
1083
1084
    Chosen.prototype.remove = function() {
1085
	this.reset_tab_index();
1086
	this.unregister_observers();
1087
	return this.remove_html();
1088
    };
1089
1090
    Chosen.prototype.keydown_arrow = function() {
1091
      var next_sib;
1092
1093
      if (this.results_showing && this.result_highlight) {
1094
        next_sib = this.result_highlight.nextAll("li.active-result").first();
1095
        if (next_sib) {
1096
          return this.result_do_highlight(next_sib);
1097
        }
1098
      } else {
1099
        return this.results_show();
1100
      }
1101
    };
1102
1103
    Chosen.prototype.keyup_arrow = function() {
1104
      var prev_sibs;
1105
1106
      if (!this.results_showing && !this.is_multiple) {
1107
        return this.results_show();
1108
      } else if (this.result_highlight) {
1109
        prev_sibs = this.result_highlight.prevAll("li.active-result");
1110
        if (prev_sibs.length) {
1111
          return this.result_do_highlight(prev_sibs.first());
1112
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1113
          if (this.choices_count() > 0) {
1114
            this.results_hide();
1115
          }
1116
          return this.result_clear_highlight();
1117
        }
1118
      }
1119
    };
1120
1121
    Chosen.prototype.keydown_backstroke = function() {
1122
      var next_available_destroy;
1123
1124
      if (this.pending_backstroke) {
1125
        this.choice_destroy(this.pending_backstroke.find("a").first());
1126
        return this.clear_backstroke();
1127
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1128
        next_available_destroy = this.search_container.siblings("li.search-choice").last();
1129
        if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1130
          this.pending_backstroke = next_available_destroy;
1131
          if (this.single_backstroke_delete) {
1132
            return this.keydown_backstroke();
1133
          } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
1134
            return this.pending_backstroke.addClass("search-choice-focus");
1135
          }
1136
        }
1137
      }
1138
    };
1139
1140
    Chosen.prototype.clear_backstroke = function() {
1141
      if (this.pending_backstroke) {
1142
        this.pending_backstroke.removeClass("search-choice-focus");
1143
      }
1144
      return this.pending_backstroke = null;
1145
    };
1146
1147
    Chosen.prototype.keydown_checker = function(evt) {
1148
      var stroke, _ref1;
1149
1150
      stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1151
      this.search_field_scale();
1152
      if (stroke !== 8 && this.pending_backstroke) {
1153
        this.clear_backstroke();
1154
      }
1155
      switch (stroke) {
1156
        case 8:
1157
          this.backstroke_length = this.search_field.val().length;
1158
          break;
1159
        case 9:
1160
          if (this.results_showing && !this.is_multiple) {
1161
            this.result_select(evt);
1162
          }
1163
          this.mouse_on_container = false;
1164
          break;
1165
        case 13:
1166
          evt.preventDefault();
1167
          break;
1168
        case 38:
1169
          evt.preventDefault();
1170
          this.keyup_arrow();
1171
          break;
1172
        case 40:
1173
          evt.preventDefault();
1174
          this.keydown_arrow();
1175
          break;
1176
      }
1177
    };
1178
1179
    Chosen.prototype.search_field_scale = function() {
1180
      var div, f_width, h, style, style_block, styles, w, _i, _len;
1181
1182
      if (this.is_multiple) {
1183
        h = 0;
1184
        w = 0;
1185
        style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1186
        styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1187
        for (_i = 0, _len = styles.length; _i < _len; _i++) {
1188
          style = styles[_i];
1189
          style_block += style + ":" + this.search_field.css(style) + ";";
1190
        }
1191
        div = $('<div />', {
1192
          'style': style_block
1193
        });
1194
        div.text(this.search_field.val());
1195
        $('body').append(div);
1196
        w = div.width() + 25;
1197
        div.remove();
1198
        f_width = this.container.outerWidth();
1199
        if (w > f_width - 10) {
1200
          w = f_width - 10;
1201
        }
1202
        return this.search_field.css({
1203
          'width': w + 'px'
1204
        });
1205
      }
1206
    };
1207
1208
    return Chosen;
1209
1210
  })(AbstractChosen);
1211
1212
  root.Chosen = Chosen;
1213
1214
}).call(this);
1215